
#include			<iostream>
#include			"PluginManager.h"

# ifdef			_WIN32
std::string ext = "*.dll";
# endif

# ifdef			__linux__
std::string ext = "*.so";
# endif

PluginManager::PluginManager(std::string dir, BabelApi *api) : _dir(dir), _api(api)
{
}

PluginManager::~PluginManager()
{
	size_t		cnt = 0;

	for (std::map<std::string, IModule *>::iterator it = _plugins.begin(); it != _plugins.end(); ++it)
		delete it->second;
	while (cnt < _libs.size())
	{
		_libs[cnt]->unload();
		delete _libs[cnt++];
	}
}

void			PluginManager::load()
{
	typedef		IModule *(*getclass)();
	getclass	func;
	QDir		*qdir = new QDir(QString(_dir.c_str()));
	QStringList	list = qdir->entryList(QStringList(ext.c_str())); 
	IModule		*mod;

	foreach(QString str, list)  
	{
		QLibrary	*lib = new QLibrary(QString(_dir.c_str()) + "/" + str);
		if (lib->load())
		{
			QString nameFunc = "get" + str;
			if ((func = reinterpret_cast<getclass>(lib->resolve(nameFunc.mid(0, nameFunc.size() - (ext.size() - 1)).toStdString().c_str()))) != 0)
				{
					mod = (*func)();
					mod->setApi(_api);
					mod->init();
					_plugins[str.mid(0, str.size() - (ext.size() - 1)).toStdString()] = mod;
				}
			_libs.push_back(lib);
			std::cout << "Lib load : " << str.toStdString() << std::endl;
		}
		else
			delete lib;
	}
	delete qdir;
}

IModule			*PluginManager::getPlugin(const std::string &key)
{
	if (_plugins.find(key) != _plugins.end())
		return _plugins[key];
	return NULL;
}

void			PluginManager::setApi(BabelApi *api)
{
	_api = api;
}

IModule			*PluginManager::getPluginProtocol(Protocol proto)
{
	std::map<std::string, IModule *>::iterator	it;
	size_t										cnt;
	std::vector<Protocol>						list;

	for (it = _plugins.begin(); it != _plugins.end(); ++it)
	{
		cnt = 0;
		list = it->second->getProtocol();
		while (cnt < list.size())
		{
			if (list[cnt] == proto)
				return it->second;
			cnt++;
		}
	}
	return NULL;
}